package com.xl.qa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xl.basic.entity.Result;
import com.xl.basic.entity.ResultEnums;
import com.xl.basic.entity.SPage;
import com.xl.basic.entity.UserInfo;
import com.xl.basic.entity.param.QueryUserParam;
import com.xl.dao.domain.XlQuestion;
import com.xl.dao.domain.XlQuestionForm;
import com.xl.dao.domain.XlUser;
import com.xl.dao.domain.XlVisitLog;
import com.xl.dao.mapper.XlQuestionMapper;
import com.xl.qa.entity.param.AddOrUpdQuestionFormParam;
import com.xl.qa.entity.param.AddQuestionParam;
import com.xl.qa.entity.param.QueryQuestionParam;
import com.xl.qa.entity.param.UpdQuestionParam;
import com.xl.qa.entity.result.QuestionDetailsResult;
import com.xl.qa.service.QuestionFormService;
import com.xl.qa.service.QuestionService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author 钟勇
 * Create in 2024/1/15 16:25
 */
@Service
@RequiredArgsConstructor
public class QuestionServiceImpl implements QuestionService {

    private final XlQuestionMapper questionMapper;
    private final QuestionFormService questionFormService;


    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 300)
    public Result<Integer> addQuestion(@NonNull AddQuestionParam param, UserInfo operator) {
        String operatorUserId = operator != null ? operator.getUserId() : null;
        XlQuestion data = BeanUtil.copyProperties(param, XlQuestion.class);
        data.setState(1)
                .setAddTime(LocalDateTime.now())
                .setAddUser(operatorUserId)
        ;

        if (questionMapper.insert(data) == 0) {
            return ResultEnums.Exception.getResult("数据写入失败");
        }
        Integer questionId = data.getQuestionId();

        if (StrUtil.isNotBlank(param.getFormJsonStr())) {
            Result<Object> formRes = questionFormService.addOrUpdQuestionForm(new AddOrUpdQuestionFormParam()
                            .setQuestionId(questionId)
                            .setFormJsonStr(param.getFormJsonStr())
                    , operator
            );

            if (formRes.isErr()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return formRes.create();
            }
        }

        return ResultEnums.Success.getDataResult(questionId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 300)
    public Result<Object> updQuestion(@NonNull UpdQuestionParam param, UserInfo operator) {
        String operatorUserId = operator != null ? operator.getUserId() : null;
        XlQuestion data = BeanUtil.copyProperties(param, XlQuestion.class);
        data.setState(1)
                .setUpdTime(LocalDateTime.now())
                .setUpdUser(operatorUserId)
        ;
        if (questionMapper.updateById(data) == 0) {
            return ResultEnums.Exception.getResult("数据编辑失败");
        }

        if (StrUtil.isNotBlank(param.getFormJsonStr())) {
            Result<Object> formRes = questionFormService.addOrUpdQuestionForm(new AddOrUpdQuestionFormParam()
                            .setQuestionId(param.getQuestionId())
                            .setFormJsonStr(param.getFormJsonStr())
                    , operator
            );

            if (formRes.isErr()) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return formRes.create();
            }
        }

        return ResultEnums.Success.getResult();
    }

    @Override
    public Result<QuestionDetailsResult> getQuestionDetails(@NonNull Integer questionId) {
        XlQuestion ques = questionMapper.selectById(questionId);
        if (ques == null || ques.getState() != 1) {
            return ResultEnums.BusinessError.getResult("问卷未找到");
        }

        QuestionDetailsResult data = BeanUtil.copyProperties(ques, QuestionDetailsResult.class);
        Result<List<XlQuestionForm>> formRes = questionFormService.queryQuestionForm(questionId);
        if (formRes.isErr()) {
            return formRes.create();
        }
        List<XlQuestionForm> form = formRes.getResult();
        data.setForm(form);

        return ResultEnums.Success.getDataResult(data);
    }

    @Override
    public Result<List<XlQuestion>> queryQuestionList(@NonNull QueryQuestionParam param) {
        List<XlQuestion> list = questionMapper.selectList(getQueryQuesWrapper(param));
        return ResultEnums.Success.getListResult(list);
    }

    @Override
    public Result<List<XlQuestion>> queryQuestionPage(@NonNull QueryQuestionParam param, SPage sPage) {
        Page<XlQuestion> page = questionMapper.selectPage(SPage.getPage(sPage), getQueryQuesWrapper(param));
        return ResultEnums.Success.getPageResult(page);
    }

    private Wrapper<XlQuestion> getQueryQuesWrapper(@NonNull QueryQuestionParam param) {
        return new LambdaQueryWrapper<XlQuestion>()
                .eq(XlQuestion::getState, 1)
                .eq(param.getQuestionId() != null, XlQuestion::getQuestionId, param.getQuestionId())
                .eq(param.getDisableFlag() != null, XlQuestion::getDisableFlag, 0)
                .like(StrUtil.isNotBlank(param.getQuestionTitleLike()), XlQuestion::getQuestionTitle, param.getQuestionTitleLike())
                .orderByAsc(XlQuestion::getDisableFlag)
                .orderByAsc(XlQuestion::getSortIndex)
                .orderByDesc(XlQuestion::getAddTime)
                ;
    }


}
